﻿using Digitalmes.WebApi.Infrastructure.Jwt;

namespace Digitalmes.WebApi.Services;

/// <summary>
/// 当前访问的用户信息。
/// </summary>
public sealed class CurrentUser(IHttpContextAccessor httpContextAccessor) : ICurrentUser
{
    private long? _userId;
    private string? _userName;
    private string[]? _roles;
    private long? _tenantId;

    public long? UserId =>
        _userId ??= StringToInt64(() => GetClaim(ClaimTypes.NameIdentifier)?.Value); // ClaimTypes 与 JwtRegisteredClaimNames 需要处理

    public string? Username => _userName ??= httpContextAccessor.HttpContext?.User.Identity?.Name;

    public string[] Roles
    {
        get
        {
            if (_roles?.Length > 0)
            {
                return _roles;
            }

            var roles = httpContextAccessor.HttpContext?.User.Claims
                .Where(s => s.Type == ClaimTypes.Role)
                .Select(s => s.Value)
                .ToArray();
            return _roles ??= (roles ?? []);
        }
    }

    public long? TenantId => _tenantId ??= StringToInt64(() => GetClaim(nameof(JwtToken.TenantId))?.Value);

    private Claim? GetClaim(string type) => httpContextAccessor.HttpContext?.User.Claims.FirstOrDefault(s => s.Type == type);

    private static long? StringToInt64(Func<string?> func)
    {
        string? value = func();
        return value != null ? Convert.ToInt64(value) : default;
    }
}
